package repository

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntityManager"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/FileName"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Json"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	"go-fox-edge-kernel-manager/repository/cloudRemoteService"
)

type repoLocalCompUpload struct {
}

func (e *repoLocalCompUpload) UploadEntity(compId int64, commitKey, description string) (map[string]interface{}, error) {
	entity := commEntityManager.GetEntityById(edgeEntity.Type.RepoCompEntity.Type(), compId)
	if entity == nil {
		return nil, errors.New("实体不存在")
	}
	compEntity := entity.(*edgeEntity.RepoCompEntity)

	if compEntity.CompRepo == "local" && compEntity.CompType == "jar-decoder" {
		return e.uploadJarDecoderEntity(compEntity.CompParam, commitKey)
	}
	if compEntity.CompRepo == "local" && compEntity.CompType == "jsp-decoder" {
		return e.uploadJspDecoderEntity(compEntity, commitKey, description)
	}
	if compEntity.CompRepo == "local" && compEntity.CompType == "jsn-decoder" {
		return e.uploadJsnDecoderEntity(compEntity, commitKey, description)
	}
	if compEntity.CompRepo == "local" && compEntity.CompType == "device-template" {
		return e.uploadDevTemplateEntity(compEntity, commitKey, description)
	}
	if compEntity.CompRepo == "local" && compEntity.CompType == "iot-template" {
		return e.uploadIotTemplateEntity(compEntity, commitKey, description)
	}

	return nil, errors.New("该组件类型，不支持本地上传")
}

func (e *repoLocalCompUpload) uploadJarDecoderEntity(compParam map[string]interface{}, commitKey string) (map[string]interface{}, error) {
	modelName := Map.GetString(compParam, "modelName", "")
	deviceType := Map.GetString(compParam, "deviceType", "")
	manufacturer := Map.GetString(compParam, "manufacturer", "")
	fileName := Map.GetString(compParam, "fileName", "")

	if Method.HasEmpty(modelName, deviceType, manufacturer, fileName, commitKey) {
		return nil, errors.New("缺少参数： modelName, deviceType, manufacturer, fileName, commitKey")
	}

	filePath := LocalPathName.getPathName4LocalJarDecoder2file(modelName)
	if !FileName.IsFile(filePath) {
		return nil, errors.New("文件不存在")
	}

	formData := make(map[string]string)
	formData["modelType"] = "decoder"
	formData["modelName"] = modelName
	formData["modelVersion"] = "v1"
	formData["component"] = "service"
	formData["workMode"] = ""
	formData["osType"] = ""
	formData["cpuArch"] = ""
	formData["commitKey"] = commitKey

	return cloudRemoteService.ExecuteUpload("/manager/repository/component/upload", filePath, formData)
}

func (e *repoLocalCompUpload) uploadJspDecoderEntity(repoCompEntity *edgeEntity.RepoCompEntity, commitKey, description string) (map[string]interface{}, error) {
	compParam := repoCompEntity.CompParam

	compId := Map.GetString(compParam, "compId", "")
	deviceType := Map.GetString(compParam, "deviceType", "")
	manufacturer := Map.GetString(compParam, "manufacturer", "")
	if Method.HasEmpty(compId, deviceType, manufacturer) {
		return nil, errors.New("缺少参数：compId, deviceType, manufacturer")
	}

	entityList := commEntityManager.FindEntityList(edgeEntity.Type.OperateEntity.Type(), func(value commEntity.IEntity) bool {
		entity := value.(*edgeEntity.OperateEntity)

		return entity.Manufacturer == manufacturer && entity.DeviceType == deviceType && entity.EngineType == "JavaScript"
	})

	body := Json.BuildMap(compParam)
	body["compId"] = compId
	body["commitKey"] = commitKey
	body["description"] = description
	body["operates"] = commEntity.BuildMapList(entityList)

	respond, err := cloudRemoteService.ExecutePost("/manager/repository/component/script/version/entity", body)
	if err != nil {
		return nil, err
	}

	// 更新版本信息
	err = e.updateVersion(repoCompEntity, respond)
	if err != nil {
		return nil, err
	}

	return respond, nil
}

func (e *repoLocalCompUpload) uploadJsnDecoderEntity(repoCompEntity *edgeEntity.RepoCompEntity, commitKey, description string) (map[string]interface{}, error) {
	compParam := repoCompEntity.CompParam

	compId := Map.GetString(compParam, "compId", "")
	deviceType := Map.GetString(compParam, "deviceType", "")
	manufacturer := Map.GetString(compParam, "manufacturer", "")
	if Method.HasEmpty(compId, deviceType, manufacturer) {
		return nil, errors.New("缺少参数：compId, deviceType, manufacturer")
	}

	entityList := commEntityManager.FindEntityList(edgeEntity.Type.DeviceModelEntity.Type(), func(value commEntity.IEntity) bool {
		entity := value.(*edgeEntity.DeviceModelEntity)

		return entity.Manufacturer == manufacturer && entity.DeviceType == deviceType
	})

	body := Json.BuildMap(compParam)
	body["compId"] = compId
	body["commitKey"] = commitKey
	body["description"] = description
	body["objects"] = commEntity.BuildMapList(entityList)

	respond, err := cloudRemoteService.ExecutePost("/manager/repository/component/model/version/entity", body)
	if err != nil {
		return nil, err
	}

	// 更新版本信息
	err = e.updateVersion(repoCompEntity, respond)
	if err != nil {
		return nil, err
	}

	return respond, nil
}

func (e *repoLocalCompUpload) uploadDevTemplateEntity(repoCompEntity *edgeEntity.RepoCompEntity, commitKey, description string) (map[string]interface{}, error) {
	compParam := repoCompEntity.CompParam

	compId := Map.GetString(compParam, "compId", "")
	deviceType := Map.GetString(compParam, "deviceType", "")
	manufacturer := Map.GetString(compParam, "manufacturer", "")
	subsetName := Map.GetString(compParam, "subsetName", "")
	if Method.HasEmpty(compId, deviceType, manufacturer, subsetName) {
		return nil, errors.New("缺少参数：compId, deviceType, manufacturer, subsetName")
	}

	entityList := commEntityManager.FindEntityList(edgeEntity.Type.DeviceTemplateEntity.Type(), func(value commEntity.IEntity) bool {
		entity := value.(*edgeEntity.DeviceTemplateEntity)

		return entity.Manufacturer == manufacturer && entity.DeviceType == deviceType && entity.SubsetName == subsetName
	})

	body := Json.BuildMap(compParam)
	body["compId"] = compId
	body["commitKey"] = commitKey
	body["description"] = description
	body["objects"] = commEntity.BuildMapList(entityList)

	respond, err := cloudRemoteService.ExecutePost("/manager/repository/component/dev-template/version/entity", body)
	if err != nil {
		return nil, err
	}

	// 更新版本信息
	err = e.updateVersion(repoCompEntity, respond)
	if err != nil {
		return nil, err
	}

	return respond, nil
}

func (e *repoLocalCompUpload) uploadIotTemplateEntity(repoCompEntity *edgeEntity.RepoCompEntity, commitKey, description string) (map[string]interface{}, error) {
	compParam := repoCompEntity.CompParam

	compId := Map.GetString(compParam, "compId", "")
	iotName := Map.GetString(compParam, "iotName", "")
	subsetName := Map.GetString(compParam, "subsetName", "")
	if Method.HasEmpty(compId, iotName, subsetName) {
		return nil, errors.New("缺少参数：compId, iotName, subsetName")
	}

	entityList := commEntityManager.FindEntityList(edgeEntity.Type.IotTemplateEntity.Type(), func(value commEntity.IEntity) bool {
		entity := value.(*edgeEntity.IotTemplateEntity)

		return entity.IotName == iotName && entity.SubsetName == subsetName
	})

	body := Json.BuildMap(compParam)
	body["compId"] = compId
	body["commitKey"] = commitKey
	body["description"] = description
	body["objects"] = commEntity.BuildMapList(entityList)

	respond, err := cloudRemoteService.ExecutePost("/manager/repository/component/iot-template/version/entity", body)
	if err != nil {
		return nil, err
	}

	// 更新版本信息
	err = e.updateVersion(repoCompEntity, respond)
	if err != nil {
		return nil, err
	}

	return respond, nil
}

func (e *repoLocalCompUpload) updateVersion(repoCompEntity *edgeEntity.RepoCompEntity, respond map[string]interface{}) error {
	// 读取对象信息
	entity := commEntityManager.GetEntityById(repoCompEntity.Type(), repoCompEntity.GetBaseEntity().Id)
	if entity == nil {
		return errors.New("实体不存在")
	}

	data := Map.GetMap(respond, "data", make(map[string]interface{}))

	installVersion := make(map[string]interface{})
	installVersion["id"] = data["id"]
	installVersion["updateTime"] = data["updateTime"]
	installVersion["description"] = data["description"]

	entity.(*edgeEntity.RepoCompEntity).CompParam["installVersion"] = installVersion

	// 保存修改
	commEntityManager.UpdateEntity(entity)
	return nil
}
